package com.kalvan.web.config;

import com.kalvan.web.exception.ExceptionHandle;
import com.kalvan.web.feign.FeignLoggerFactory;
import com.kalvan.web.feign.FeignRequestInterceptor;
import com.kalvan.web.feign.FeignResponseDecoder;
import com.kalvan.web.i18n.MessageResource;
import com.kalvan.web.servlet.WebMvcConfig;
import com.kalvan.web.servlet.request.RequestHandler;
import com.kalvan.web.servlet.response.ResponseHandler;
import feign.Logger;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * kalvan web配置
 *
 * @author chenliang
 */
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@Configuration
public class KalvanWebConfig {
    /**
     * 国际化
     *
     * @return ResourceBundleMessageSource
     */
    @ConditionalOnProperty(name = "kalvan.web.messageSource.enabled", matchIfMissing = true)
    @ConditionalOnMissingBean
    @Bean
    public ResourceBundleMessageSource messageResource() {
        return new MessageResource();
    }

    /**
     * web拦截器
     * 默认加载 CallInterfaceInterceptor
     * 默认加载 MessageResourceInterceptor
     *
     * @return WebMvcConfigurer
     */
    @ConditionalOnProperty(name = "kalvan.web.webMvcConfigurer.enabled", matchIfMissing = true)
    @ConditionalOnMissingBean
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfig();
    }

    /**
     * web统一异常Advice
     *
     * @return ExceptionHandle
     */
    @ConditionalOnProperty(name = "kalvan.web.exceptionHandle.enabled", matchIfMissing = true)
    @ConditionalOnMissingBean
    @Bean
    public ExceptionHandle exceptionHandle() {
        @ControllerAdvice
        class DefaultExceptionHandle extends ExceptionHandle {
            public DefaultExceptionHandle() {
                super();
            }
        }
        return new DefaultExceptionHandle();
    }

    /**
     * web统一请求拦截器Advice
     *
     * @return RequestHandler
     */
    @ConditionalOnProperty(name = "kalvan.web.requestHandler.enabled", matchIfMissing = true)
    @ConditionalOnMissingBean
    @Bean
    public RequestHandler requestHandler() {
        @ControllerAdvice
        class DefaultRequestHandler extends RequestHandler {
            public DefaultRequestHandler() {
                super();
            }
        }
        return new DefaultRequestHandler();
    }

    /**
     * web统一返回拦截器Advice
     *
     * @return ResponseHandler
     */
    @ConditionalOnProperty(name = "kalvan.web.responseHandler.enabled", matchIfMissing = true)
    @ConditionalOnMissingBean
    @Bean
    public ResponseHandler responseHandler() {
        @ControllerAdvice
        class DefaultResponseHandler extends ResponseHandler {
            public DefaultResponseHandler() {
                super();
            }
        }
        return new DefaultResponseHandler();
    }

    /**
     * feign 日志记录重写
     *
     * @return FeignLoggerFactory
     */
    @ConditionalOnMissingBean
    @Bean
    public org.springframework.cloud.openfeign.FeignLoggerFactory feignLoggerFactory() {
        return new FeignLoggerFactory();
    }

    /**
     * feign 日志级别
     *
     * @return Level
     */
    @ConditionalOnMissingBean(Logger.Level.class)
    @Bean
    Logger.Level feignLevel() {
        return Logger.Level.FULL;
    }

    /**
     * feign 请求拦截器实现mock功能
     *
     * @return FeignRequestInterceptor
     */
    @ConditionalOnProperty(name = "kalvan.web.mock.enabled")
    @ConditionalOnMissingBean
    @Bean
    FeignRequestInterceptor requestInterceptor() {
        return new FeignRequestInterceptor();
    }

//    /**
//     * feign 请求统一Mock
//     *
//     * @return FeignMockClient
//     */
//    @ConditionalOnProperty(name = "kalvan.web.mock.enabled")
//    @ConditionalOnMissingBean
//    @Bean
//    FeignMockClient mockFeignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
//        return new FeignMockClient(cachingFactory, clientFactory);
//    }

    /**
     * feign 返回拦截器
     *
     * @return FeignResponseDecoder
     */
    @ConditionalOnProperty(name = "kalvan.web.feignResponseDecoder.enabled")
    @ConditionalOnMissingBean
    @Bean
    FeignResponseDecoder feignResponseDecoder() {
        return new FeignResponseDecoder();
    }


}
